Skip to main content

Cucumber with Selenium (UI Automation Patterns)

When using Cucumber for UI automation, how you structure Selenium code matters more than the tools themselves. This section explains clean, scalable patterns for combining Cucumber with Selenium in real projects.


Core Principle

Feature files describe behavior.
Step definitions orchestrate actions.
Page Objects perform UI interactions.

Never mix these responsibilities.


Feature Files (Gherkin)

Step Definitions (Glue)

Page Objects (UI Actions)

WebDriver / Selenium APIs

This separation ensures:

  • Readability
  • Reusability
  • Maintainability

Role of Feature Files

Feature files should:

  • Describe user behavior
  • Avoid UI details
  • Stay business-readable

❌ Avoid:

  • Button names
  • XPath/CSS
  • Page names

Role of Step Definitions

Step definitions should:

  • Translate behavior into actions
  • Call Page Object methods
  • Contain minimal logic

❌ Avoid:

  • Direct Selenium calls
  • Long workflows
  • Assertions-heavy logic

Role of Page Objects

Page Objects should:

  • Contain Selenium locators
  • Encapsulate UI actions
  • Hide implementation details

Benefits:

  • Locator changes affect one place
  • Steps remain clean
  • Easier maintenance

Assertions Placement

Best practice:

  • Assertions in step definitions or helper/assertion layers
  • Not inside feature files
  • Not buried deep inside page objects

Rule:

Page Objects act, Steps verify.


Driver Management (Conceptual)

Driver lifecycle should be:

  • Controlled via Hooks
  • One driver per scenario (for parallel safety)
  • Cleaned up after execution

Avoid:

  • Static WebDriver
  • Sharing drivers across scenarios

Synchronization Awareness

UI automation requires:

  • Explicit waits
  • Stable element interaction patterns

Avoid:

  • Hard sleeps
  • Timing assumptions

Common Anti-Patterns ❌

  • Selenium code inside step definitions
  • Huge step methods
  • Duplicate locators across steps
  • UI logic leaking into Gherkin

These lead to:

  • High maintenance
  • Flaky tests
  • Poor readability

Real-World Folder Structure (Example)

src/test/java
├── steps
├── pages
├── hooks
├── runners
├── utils

Clean separation = scalable framework.


Interview-Ready Questions

Q: Where should Selenium code live in Cucumber?
A: Inside Page Objects, not step definitions.

Q: Why avoid Selenium calls in step definitions?
A: To improve reuse and maintainability.


Key Takeaways

  • Separate behavior from implementation
  • Use Page Object pattern
  • Keep step definitions thin
  • Manage driver via hooks
  • Avoid UI details in Gherkin